/**
 * 请求的工具类封装，封装方法如下：
 * ajax: 执行Ajax请求
 * post: 封装post, 验证token是否存在
 * postForm: 表单的提交统一认证，进行表单的校验，同时校验token
 * postFree: 封装post 不添加 token
 * get: 封装get, 验证token是否存在
 * getFree: 封装get 不添加 token
 *  */
import storage from "@/store/storage";
import { notify, loading } from "@/assets/js/util";
import $router from "@/router/index";

const tokenKey = window.globle.tokenKey;

/*ajax操作*/
let _$ = {};

// 创建用于网络请求的对象
let createXHR = function() {
  if (typeof XMLHttpRequest != "undefined") {
    return new XMLHttpRequest();
  } else if (typeof ActiveXObject != "undefined") {
    if (typeof arguments.callee.activeXString != "string") {
      var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],
        i, len;
      for (var i = 0, len = versions.length; i < len; i++) {
        try {
          new ActiveXObect(versions[i]);
          arguments.callee.activeXString = versions[i];
          break;
        } catch (ex) {
          //跳过
        }
      }
    }
    return new ActiveXObect(arguments.callee.activeXString);
  } else {
    throw new Error("No XHRobject available.");
  }
};

/**
 * 执行Ajax请求
 * @param {
 *   url: "",  // 请求的路径
 *   type: "GET", // 请求的方式GET、POST
 *   data: {},  // 请求的参数，可以为Object 或者 FormData  ,key-value模式，value不能为对象
 *   dataType: "JSON", // 默认 "JSON" ，还可以为 "TEXT" 等
 *   responseType: "", // 默认返回字符，支持"arraybuffer"
 *   beforeSend: function (xhr) { },  // 请求发送之前处理的方法
 *   success: function (response, xhr) { }, // 请求成功200的方法
 *   error: function (response, xhr) { } // 请求失败的方法
 * } options 请求参数
 */
_$.ajax = function(options) {
  // 默认参数信息
  var defOption = {
    url: "", // 请求的路径
    type: "GET", // 请求的方式GET、POST
    data: {}, // 请求的参数，可以为Object 或者 FormData
    dataType: "JSON", // 默认 "JSON" ，还可以为 TEXT 等
    responseType: "", // 默认返回字符，支持"arraybuffer"
    beforeSend: function(xhr) {}, // 请求发送之前处理的方法
    success: function(response, xhr) {}, // 请求成功200的方法
    error: function(response, xhr) {} // 请求失败的方法
  }

  // 参数合并及处理
  options.url = options.url || defOption.url;
  options.type = options.type ? options.type.toUpperCase() : defOption.type;
  options.data = options.data || defOption.data;
  options.dataType = options.dataType ? options.dataType.toUpperCase() : defOption.dataType;
  options.responseType = options.responseType || defOption.responseType;
  options.beforeSend = options.beforeSend || defOption.beforeSend;
  options.success = options.success || defOption.success;
  options.error = options.error || defOption.error;

  // 请求参数的处理
  var paramStr = "",
    paramData = null;
  if (options.type === "GET") {
    paramStr = "?";
    if (options.data instanceof FormData) {
      for (let [key, value] of options.data.entries()) {
        paramStr += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
      }
    } else {
      for (var i in options.data) {
        paramStr += encodeURIComponent(i) + "=" + encodeURIComponent(options.data[i]) + "&";
      }
    }
    paramStr = paramStr.substring(0, paramStr.length - 1);
  } else if (options.type === "POST") {
    // 请求参数进行整理
    paramData = new FormData();
    if (options.data instanceof FormData) {
      paramData = options.data;
    } else {
      for (var index in options.data) {
        if (options.data.hasOwnProperty(index)) {
          // paramData.append(index, encodeURI(options.data[index]));
          paramData.append(index, options.data[index]);
        }
      }
    }
  }

  var xhr = createXHR();
  // 请求返回后执行的方法
  xhr.onreadystatechange = function() {
    if (xhr.readyState != 4) return; // 仅处理请求完成的事件

    var response = {};
    if (options.responseType === "arraybuffer") {
      response = xhr.response;
    } else {
      response = xhr.responseText;
      if (options.dataType === "JSON") {
        try {
          response = JSON.parse(response);
        } catch (err) {
          if (response.indexOf("SYSTEMLOGINPAGEMARKER") !== -1 || response.indexOf("未知页面") !== -1) {
            response = { code: 401, msg: "未授权的页面!", data: response };
          } else {
            response = { code: 500, msg: "返回信息解析错误!", data: response };
          }
        }
      }
    }

    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
      options.success(response, xhr);
    } else {
      options.error(response, xhr);
    }
  };

  // 进行请求
  xhr.open(options.type, options.url + paramStr, true);
  xhr.responseType = options.responseType;
  xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  options.beforeSend && options.beforeSend(xhr); // 植入一个请求前处理的方法

  xhr.send(paramData);
};

//token失效
let tokenInvalid = function() {
  storage.removeUser();
  storage.removeDict();
  storage.delToken();
  storage.removeMenus();
  storage.removePowers();
  storage.removeConfigs();
  storage.setLoginState(false);
  $router.push({ path: window.global.loginPath });
};

/**
 * 封装post, 验证token是否存在
 * @param param FormData 或 {}对象
 * @param url url
 * @param success 成功回调
 */
_$.post = function(param, url, success, error) {
  // 验证token是否存在，如果存在，则进行请求，如果不存在，直接标记为退出
  var token = storage.getToken();
  if (!token) {
    notify.warning("当前 平台凭证 验证失败!", 5000);
    tokenInvalid();
    return;
  }

  _$.ajax({
    url: url,
    type: "POST",
    data: param,
    beforeSend: function(xhr) {
      xhr.setRequestHeader(tokenKey, storage.getToken()); // 头部加入token信息
      loading.show();
    },
    success: function(response, xhr) {
      loading.hide(); // 请求完成，关掉loadingbar
      // Token认证失效的处理
      if (response.code == 401 || response.code == 403) {
        tokenInvalid();
        return;
      }

      storage.refreshToken(); //本地token刷新时间
      // 成功后对数据进行处理
      if (response.code == 200) {
        success && success(response);
      } else if (response.code == 250) {
        notify.warning(response.msg);
        success(response);
      } else {
        error && error();
        notify.error(response.msg);
      }
    },
    error: function(response, xhr) {
      loading.hide();
      error && error();
      notify.error("请求错误：" + response);
    }
  });
};

/**
 * 表单的提交统一认证，进行表单的校验，同时校验token
 * @param formRef 表单的引用
 * @param param formdata或者{}对象
 * @param url url
 * @param success 成功回调
 */
_$.postForm = function(formRef, param, url, success, error) {
  formRef.validate(valid => {
    if (valid) {
      _$.post(param, url, function(_r) {
        success(_r);
      }, function() {
        error && error();
      });
    } else {
      error && error();
      notify.warning("表单校验失败，请修改");
    }
  });
};

/**
 * 封装post 不添加 token
 * @param param formdata或者{}对象
 * @param url url
 * @param success 成功回调
 */
_$.postFree = function(param, url, success, error) {
  _$.ajax({
    url: url, // 请求的路径
    type: "POST", // 请求的方式GET、POST
    data: param, // 请求的参数，可以为Object 或者 FormData
    beforeSend: function(xhr) {
      loading.show();
    },
    success: function(response, xhr) {
      loading.hide(); // 请求完成，关掉loadingbar

      // 成功后对数据进行处理
      if (response.code == 200) {
        success && success(response);
      } else if (response.code == 250) {
        notify.warning(response.msg);
        success(response);
      } else {
        error && error();
        notify.error(response.msg);
      }
    },
    error: function(response, xhr) {
      loading.hide();
      error && error();
      notify.error("请求错误：" + response);
    }
  });
};

/**
 * 封装get, 验证token是否存在
 * @param param FormData 或 {}对象
 * @param url url
 * @param success 成功回调
 */
_$.get = function(param, url, success) {
  // 验证token是否存在，如果存在，则进行请求，如果不存在，直接标记为退出
  var token = storage.getToken();
  if (!token) {
    notify.warning("当前 平台凭证 验证失败!", 5000);
    tokenInvalid();
  }

  _$.ajax({
    url: url,
    type: "GET",
    data: param, // 请求的参数，可以为Object 或者
    beforeSend: function(xhr) {
      xhr.setRequestHeader(tokenKey, storage.getToken());
      loading.show();
    }, // 请求发送之前处理的方法
    success: function(response, xhr) {
      loading.hide(); // 请求完成，关掉loadingbar
      // Token认证失效的处理
      if (response.code == 401 || response.code == 403) {
        tokenInvalid();
        return;
      }

      storage.refreshToken(); //本地token刷新时间
      // 成功后对数据进行处理
      if (response.code == 200) {
        success && success(response);
      } else if (response.code == 250) {
        notify.warning(response.msg);
        success && success(response);
      } else {
        notify.error(response.msg);
      }
    },
    error: function(response, xhr) {
      loading.hide();
      notify.error("请求错误：" + response);
    }
  });
};

/**
 * 封装get 不添加 token
 * @param param FormData 或 {}对象
 * @param url url
 * @param success 成功回调
 */
_$.getFree = function(param, url, success) {
  _$.ajax({
    url: url,
    type: "GET",
    data: param, // 请求的参数，可以为Object 或者
    beforeSend: function(xhr) {
      loading.show();
    }, // 请求发送之前处理的方法
    success: function(response, xhr) {
      loading.hide(); // 请求完成，关掉loadingbar

      // 成功后对数据进行处理
      if (response.code == 200) {
        success && success(response);
      } else if (response.code == 250) {
        notify.warning(response.msg);
        success && success(response);
      } else {
        notify.error(response.msg);
      }
    },
    error: function(response, xhr) {
      loading.hide();
      notify.error("请求错误：" + response);
    }
  });
};

export default _$;